﻿//-------------------------------------------------------
// Copyright (c)
// All rights reserved.
// 
// File Name: IOCPAppImpl.h 
// File Des: 使用iocp服务器的应用实现
// File Summary: 
// Cur Version: 1.0
// Author:
// Create Data:
// History:
//      <Author>        <Time>        <Version>      <Des>
//       lzlong        2024-1-25        1.0            
//-------------------------------------------------------
#pragma once
#include "CIOCPServerModel.h"
#include ".\misc\DeclareDefine.h"
#include ".\misc\LinkNodeT.h"

enum EmIOCPAppType
{
    APP_IOCP_NULL = 1,
    APP_IOCP_PROXY,   // 2
};

#define IOCP_DECLAREREG_CLASS(OBJ, Type)                                     \
  DECLARE_REG_CLASS(OBJ, Enum2WStr(Type),                                    \
  static_cast<int>(Type))

/// <summary>
/// iocp server 应用基类
/// </summary>
class CIOCPAppSrvBase
    : public CLinkNodeT<CIOCPAppSrvBase>
    , public IOCPServerCallBack
{
public:
    explicit CIOCPAppSrvBase(LPCSTR lpAddress, int nPort);

    virtual ~CIOCPAppSrvBase();

    // 开启服务器监听
    BOOL StartServer();

    // 停止服务器监听
    BOOL StopServer();

    ///< 获取应用类型
    virtual EmIOCPAppType GetIOCPAppType() = 0;

    ///< 获取应用Str类型
    virtual LPCWSTR GetIOCPAppTypeStr() = 0;

    /// <summary>
    ///  通过应用类型断开对应应用的全部连接
    /// </summary>
    /// <param name="emType">应用类型id</param>
    /// <returns>是否成功</returns>
    static BOOL DisconnectByIOCPAppType(EmIOCPAppType emType);

    /// <summary>
    ///  通过连接ID发送数据
    /// </summary>
    /// <param name="uiConID">连接ID</param>
    /// <param name="lpData">数据串</param>
    /// <param name="ulDataSize">数据串大小</param>
    /// <returns>是否成功</returns>
    static BOOL SendDataByConnectID(UINT uiConID, LPCSTR lpData, ULONG ulDataSize);

protected:
    // 新连接建立
    void OnConnectionEstablished(LPPER_SOCKET_CONTEXT pSocketContext) override;

    // 连接关闭
    void OnConnectionClosed(LPPER_SOCKET_CONTEXT pSocketContext) override;

    // 错误提示
    void OnOutPutMsg(const std::wstring strMsg, ...) override;

    // 连接上发生错误
    void OnConnectionError(LPPER_SOCKET_CONTEXT pSocketContext, int error) override;

    // 读操作完成
    void OnRecvCompleted(LPPER_SOCKET_CONTEXT pSocketContext, LPPER_IO_CONTEXT pIoContext, UINT uiBytesTrans) override;

    // 写操作完成
    void OnSendCompleted(LPPER_SOCKET_CONTEXT pSocketContext, LPPER_IO_CONTEXT pIoContext, UINT uiBytesTrans) override;

    // iocp失败
    void OnIOCPCaughtError(INT iIOCPErr, INT iWSAErr) override;

    // IOCP初始化ok
    void OnIOCPInitializeFinished() override;

protected:
    /// <summary>
    /// < iocp服务端对象
    /// </summary>
    CIOCPServerModel*        m_pIOCPSrvImpl;
};

/// <summary>
/// iocp app server 应用类
/// </summary>
class CAppIOCPSrvImpl : public CIOCPAppSrvBase
{
    IOCP_DECLAREREG_CLASS(CAppIOCPSrvImpl, APP_IOCP_PROXY);
public:
    explicit CAppIOCPSrvImpl();

    explicit CAppIOCPSrvImpl(LPCSTR lpAddress, int nPort);

    ~CAppIOCPSrvImpl();

    ///< 获取应用类型
    EmIOCPAppType GetIOCPAppType() override;

    ///< 获取应用Str类型
    LPCWSTR GetIOCPAppTypeStr() override;

    ///< 连接上发生错误
    void OnConnectionError(LPPER_SOCKET_CONTEXT pSocketContext, int error) override;

    ///< 读操作完成
    void OnRecvCompleted(LPPER_SOCKET_CONTEXT pSocketContext, LPPER_IO_CONTEXT pIoContext, UINT uiBytesTrans) override;

    ///< iocp失败
    void OnIOCPCaughtError(INT iIOCPErr, INT iWSAErr) override;

    // IOCP初始化ok
    void OnIOCPInitializeFinished() override;

private:
};
